home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / cfengine-1.5.3 / src / acl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-06-29  |  56.2 KB  |  2,110 lines

  1. /* cfengine for GNU
  2.  
  3.  
  4.    Copyright (C) 1995
  5.    Free Software Foundation, Inc.
  6.    
  7.    This file is part of GNU cfengine - written and maintained 
  8.    by Mark Burgess, Dept of Computing and Engineering, Oslo College,
  9.    Dept. of Theoretical physics, University of Oslo
  10.    
  11.    This program is free software; you can redistribute it and/or modify it
  12.    under the terms of the GNU General Public License as published by the
  13.    Free Software Foundation; either version 2, or (at your option) any
  14.    later version.
  15.    
  16.    This program is distributed in the hope that it will be useful,
  17.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.    GNU General Public License for more details.
  20.    
  21.    You should have received a copy of the GNU General Public License
  22.    along with this program; if not, write to the Free Software
  23.    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
  24. */
  25.  
  26. /**************************************************************************/
  27. /*                                                                        */
  28. /* File: acl.c                                                            */
  29. /* Author: Mark / Demosthenes / Patch by Goran Oberg                      */
  30. /*                                                                        */
  31. /**************************************************************************/
  32.  
  33. #include <stdio.h>
  34.  
  35. #include "cf.defs.h"
  36. #include "cf.extern.h"
  37.  
  38. #ifdef HAVE_SYS_ACL_H
  39. # include <sys/acl.h>
  40. #endif
  41.  
  42. /****** Code added for NT by J°rgen Kjensli & Bj°rn Gustafson, May 1999 *****/
  43. #ifdef NT
  44. #include <windows.h>
  45. #endif
  46. /*************************** END NT Addition *******************************/
  47.  
  48. #ifdef HAVE_DCE_DACLIF_H
  49. # include <dce/daclif.h>
  50. # include <dce/secidmap.h>
  51. # include <dce/binding.h>
  52. # include <dcedfs/aclint.h>
  53. # define SIZE_AVAIL (unsigned32) 2
  54. # define HAVE_DCE
  55.  
  56. # define MAX_TYPES          (unsigned32)2
  57. # define MAX_STRINGS        (unsigned32)16
  58. #endif
  59.  
  60. /*****************************************************************************/
  61.  
  62. char *CFFSTYPES[] =
  63. {
  64.     "posix",
  65.     "solaris",
  66.     "dfs",
  67.     "afs",
  68.     "hpux",
  69.     "nt",
  70.     NULL
  71. };
  72.  
  73. enum cffstype StringToFstype();
  74. struct CFACL *GetACL();
  75.  
  76. /*****************************************************************************/
  77.  
  78. #if defined SOLARIS && defined HAVE_SYS_ACL_H
  79. void
  80. aclsortperror(int error)
  81. {
  82.  switch (error)
  83.     {
  84.     case GRP_ERROR:
  85.     CfLog(cferror,"acl: There is more than one group_obj ACL entry.\n","");
  86.     break;
  87.     case USER_ERROR:
  88.     CfLog(cferror,"acl: There is more than one user_obj ACL entry.\n","");
  89.     break;
  90.     case CLASS_ERROR:
  91.     CfLog(cferror,"acl: There is more than one class_obj ACL entry.\n", "");
  92.     break;
  93.     case OTHER_ERROR:
  94.     CfLog(cferror,"acl: There is more than one other_obj ACL entry.\n", "");
  95.     break;
  96.     case DUPLICATE_ERROR:
  97.     CfLog(cferror,"acl: Duplicate entries of user or group.\n", "");
  98.     break;
  99.     case ENTRY_ERROR:
  100.     CfLog(cferror,"acl: The entry type is invalid.\n", "");
  101.     break;
  102.     case MISS_ERROR:
  103.     CfLog(cferror,"acl: Missing group_obj, user_obj, class_obj, or other_obj entries.\n", "");
  104.     break;
  105.     case MEM_ERROR:
  106.     CfLog(cferror,"acl: The system can't allocate any memory.\n", "");
  107.     break;
  108.     default:
  109.     sprintf(OUTPUT,"acl: Unknown ACL error code: %d !\n", error);
  110.     CfLog(cferror,OUTPUT,"");
  111.     break;
  112.     }
  113.  return;
  114. }
  115. #endif
  116.  
  117. /*****************************************************************************/
  118.  
  119. #ifdef HAVE_DCE
  120. sec_acl_entry_type_t
  121. BuildDceAclEntry_Type(char *t, char *n)
  122. {
  123.  if (strcmp(t, "user") == 0)
  124.     {
  125.     if (*n == 0)
  126.        {
  127.        return sec_acl_e_type_user_obj;
  128.        }
  129.     else
  130.        {
  131.        return sec_acl_e_type_user;
  132.        }
  133.     }
  134.  else if (strcmp(t, "group") == 0)
  135.     {
  136.     if (*n == 0)
  137.        {
  138.        return sec_acl_e_type_group_obj;
  139.        }
  140.     else
  141.        {
  142.        return sec_acl_e_type_group;
  143.        }
  144.     }
  145.  else if (strcmp(t, "other") == 0)
  146.     {
  147.     return sec_acl_e_type_other_obj;
  148.     }
  149.  else if (strcmp(t, "mask") == 0)
  150.     {
  151.     return sec_acl_e_type_mask_obj;
  152.     }
  153.  else if (strcmp(t, "any") == 0)
  154.     {
  155.     return sec_acl_e_type_any_other;
  156.     }
  157.  else if (strcmp(t, "unauthenticated") == 0)
  158.     {
  159.     return sec_acl_e_type_unauthenticated;
  160.     }
  161.  else if (strcmp(t, "foreign_other") == 0)
  162.     {
  163.     return sec_acl_e_type_foreign_other;
  164.     }
  165.  else if (strcmp(t, "foreign_user") == 0)
  166.     {
  167.     return sec_acl_e_type_foreign_user;
  168.     }
  169.  else if (strcmp(t, "foreign_group") == 0)
  170.     {
  171.     return sec_acl_e_type_foreign_group;
  172.     }
  173.  return 0;
  174. }
  175.  
  176. /*****************************************************************************/
  177.  
  178. sec_acl_permset_t
  179. BuildDceAclEntry_Perms(char *mode, sec_acl_permset_t oldmode)
  180. {
  181.  sec_acl_permset_t perm = 0;
  182.  char *a;
  183.  enum {add, del} o;
  184.  perm = oldmode;
  185.  
  186.  if (strcmp(mode, "noaccess") == 0)
  187.     {
  188.     return 0; /* No access for this user/group */
  189.     }
  190.  
  191.  o = add;
  192.  for (a = mode; *a != '\0' ; *a++)
  193.     {
  194.     if (*a == '+' || *a == ',')
  195.        {
  196.        o = add;
  197.        }
  198.     else if (*a == '-')
  199.        {
  200.        o = del;
  201.        }
  202.     else if (*a == '=')
  203.        {
  204.        o = add;
  205.        perm = 0;
  206.        }
  207.     else
  208.        {
  209.        switch (*a)
  210.       {
  211.       case 'r':
  212.           if (o == add)
  213.          {
  214.          perm |= sec_acl_perm_read;
  215.          }
  216.           else
  217.          {
  218.          perm &= ~sec_acl_perm_read;
  219.          }
  220.           break;
  221.       case 'w': 
  222.           if (o == add)
  223.          {
  224.          perm |= sec_acl_perm_write;
  225.          }
  226.           else
  227.          {
  228.          perm &= ~sec_acl_perm_write;
  229.          }
  230.           break;
  231.       case 'x': 
  232.           if (o == add)
  233.          {
  234.          perm |= sec_acl_perm_execute;
  235.          }
  236.           else
  237.          {
  238.          perm &= ~sec_acl_perm_execute;
  239.          }
  240.           break;
  241.       case 'c': 
  242.           if (o == add)
  243.          {
  244.          perm |= sec_acl_perm_control;
  245.          }
  246.           else
  247.          {
  248.          perm &= ~sec_acl_perm_control;
  249.          }
  250.           break;
  251.       case 'i': 
  252.           if (o == add)
  253.          {
  254.          perm |= sec_acl_perm_insert;
  255.          }
  256.           else
  257.          {
  258.          perm &= ~sec_acl_perm_insert;
  259.          }
  260.           break;
  261.       case 'd': 
  262.           if (o == add)
  263.          {
  264.          perm |= sec_acl_perm_delete;
  265.          }
  266.           else
  267.          {
  268.          perm &= ~sec_acl_perm_delete;
  269.          }
  270.           break;
  271.       default:  
  272.           sprintf(OUTPUT,"Invalid mode string in DCE/DFS acl: %s\n", mode);
  273.           CfLog(cferror,OUTPUT,"");
  274.       }
  275.        }
  276.     }
  277.  return perm;
  278. }
  279.  
  280. /*****************************************************************************/
  281.  
  282. uuid_t
  283. BuildDceAclEntry_Id(sec_rgy_handle_t rgy_site, sec_rgy_name_t name, sec_acl_entry_type_t type)
  284. {
  285.  uuid_t id;
  286.  error_status_t status;
  287.  
  288.  bzero(id, sizeof(id));
  289.  switch (type)
  290.     {
  291.     case sec_acl_e_type_group:
  292.     sec_id_parse_group(rgy_site, name, NULL, NULL, NULL, &id, &status);
  293.     if (status != error_status_ok)
  294.        {
  295.        sprintf(OUTPUT,"sec_rgy_parse_group: %ld\n", status);
  296.        CfLog(cferror,OUTPUT,"");
  297.        }
  298.     break;
  299.     case sec_acl_e_type_user:
  300.     sec_id_parse_name(rgy_site, name, NULL, NULL, NULL, &id, &status);
  301.     if (status != error_status_ok)
  302.        {
  303.        sprintf(OUTPUT,"sec_rgy_parse_name: %ld\n", status);
  304.        CfLog(cferror,OUTPUT,"");
  305.        }
  306.     break;
  307.     case sec_acl_e_type_foreign_group:
  308.     CfLog(cferror,"acl type c_acl_e_type_foreign_group not supported yet\n","");
  309.     break;
  310.     case sec_acl_e_type_foreign_user:
  311.     CfLog(cferror,"acl type sec_acl_e_type_foreign_user not supported yet.\n","");
  312.     break;
  313.     case sec_acl_e_type_foreign_other:
  314.     CfLog(cferror,"acl type sec_acl_e_type_foreign_other not supported yet.\n","");
  315.     break;
  316.     default:
  317.     CfLog(cferror,"Unknown acl type in BuildDceAclEntry_Id!\n","");
  318.     break;
  319.     }
  320.  return id;
  321. }
  322. #endif
  323.  
  324. /*****************************************************************************/
  325.  
  326. #if defined SOLARIS && defined HAVE_SYS_ACL_H
  327.  
  328. int
  329. ParseSolarisMode(char* mode, mode_t oldmode)
  330. {
  331.  char *a;
  332.  mode_t perm;
  333.  enum {add, del} o;
  334.  
  335.  perm = oldmode;
  336.  if (strcmp(mode, "noaccess") == 0)
  337.     {
  338.     return 0; /* No access for this user/group */
  339.     }
  340.  
  341.  o = add;
  342.  for (a = mode; *a != '\0' ; *a++)
  343.     {
  344.     if (*a == '+' || *a == ',')
  345.        {
  346.        o = add;
  347.        }
  348.     else if (*a == '-')
  349.        {
  350.        o = del;
  351.        }
  352.     else if (*a == '=')
  353.        {
  354.        o = add;
  355.        perm = 0;
  356.        }
  357.     else
  358.        {
  359.        switch (*a)
  360.       {
  361.       case 'r':
  362.           if (o == add)
  363.          {
  364.          perm |= 04;
  365.          }
  366.           else
  367.          {
  368.          perm &= ~04;
  369.          }
  370.           break;
  371.       case 'w': 
  372.           if (o == add)
  373.          {
  374.          perm |= 02;
  375.          }
  376.           else
  377.          {
  378.          perm &= ~02;
  379.          }
  380.           break;
  381.       case 'x':
  382.           if (o == add)
  383.          {
  384.          perm |= 01;
  385.          }
  386.           else
  387.          {
  388.          perm &= ~01;
  389.          }
  390.           break;
  391.       default:  
  392.           sprintf(OUTPUT,"Invalid mode string in solaris acl: %s\n", mode);
  393.           CfLog(cferror,OUTPUT,"");
  394.       }
  395.        }
  396.     }
  397.  
  398.  return perm;
  399. }
  400.  
  401. int
  402. BuildAclEntry(struct stat *sb, char *acltype, char *name, struct acl *newaclbufp)
  403. {
  404.  struct passwd *pw;
  405.  struct group *gr;
  406.  
  407.  if (strcmp(acltype, "user") == 0)
  408.     {
  409.     if (*name == 0)
  410.        {
  411.        newaclbufp->a_type = USER_OBJ;
  412.        newaclbufp->a_id = sb->st_uid;
  413.        }
  414.     else 
  415.        {
  416.        newaclbufp->a_type = USER;
  417.        if ((pw = getpwnam(name)) != NULL)
  418.       {
  419.       newaclbufp->a_id = pw->pw_uid;
  420.       }
  421.        else
  422.       {
  423.       sprintf(OUTPUT,"acl: no such user: %s\n",name);
  424.       CfLog(cferror,OUTPUT,"");
  425.       return -1;
  426.       }
  427.        }
  428.     }
  429.  else if (strcmp(acltype, "group") == 0)
  430.     {
  431.     if (*name == 0)
  432.        {
  433.        newaclbufp->a_type = GROUP_OBJ;
  434.        newaclbufp->a_id = sb->st_gid;
  435.        }
  436.     else
  437.        {
  438.        newaclbufp->a_type = GROUP;
  439.        if ((gr = getgrnam(name)) != NULL)
  440.       {
  441.       newaclbufp->a_id = gr->gr_gid;
  442.       }
  443.        else
  444.       {
  445.       sprintf(OUTPUT,"acl: no such group: %s\n",name);
  446.       CfLog(cferror,OUTPUT,"");
  447.       return -1;
  448.       }
  449.        }
  450.     }
  451.  else if (strcmp(acltype, "mask") == 0)
  452.     {
  453.     newaclbufp->a_type = CLASS_OBJ;
  454.     newaclbufp->a_id = 0;
  455.     }
  456.  else if (strcmp(acltype, "other") == 0)
  457.     {
  458.     newaclbufp->a_type = OTHER_OBJ;
  459.     newaclbufp->a_id = 0;
  460.     }
  461.  else if (strcmp(acltype, "default_user") == 0)
  462.     {
  463.     if (*name == 0)
  464.        {
  465.        newaclbufp->a_type = DEF_USER_OBJ;
  466.        newaclbufp->a_id = 0;
  467.        }
  468.     else
  469.        {
  470.        newaclbufp->a_type = DEF_USER;
  471.        if ((pw = getpwnam(name)) != NULL)
  472.       {
  473.       newaclbufp->a_id = pw->pw_uid;
  474.       }
  475.        else
  476.       {
  477.       sprintf(OUTPUT,"%s: acl: no such user: %s\n", VPREFIX, name);
  478.       CfLog(cferror,OUTPUT,"");
  479.       return -1;
  480.       }
  481.        }
  482.     }
  483.  else if (strcmp(acltype, "default_group") == 0)
  484.     {
  485.     if (*name == 0)
  486.        {
  487.        newaclbufp->a_type = DEF_GROUP_OBJ;
  488.        newaclbufp->a_id = 0;
  489.        }
  490.     else
  491.        {
  492.        newaclbufp->a_type = DEF_GROUP;
  493.        if ((gr = getgrnam(name)) != NULL)
  494.       {
  495.       newaclbufp->a_id = gr->gr_gid;
  496.       }
  497.        else
  498.       {
  499.       sprintf(OUTPUT,"acl: no such group: %s\n",name);
  500.       CfLog(cferror,OUTPUT,"");
  501.       return -1;
  502.       }
  503.        }
  504.     }
  505.  else if (strcmp(acltype, "default_mask") == 0)
  506.     {
  507.     newaclbufp->a_type = DEF_CLASS_OBJ;
  508.     newaclbufp->a_id = 0;
  509.     }
  510.  else if (strcmp(acltype, "default_other") == 0)
  511.     {
  512.     newaclbufp->a_type = DEF_OTHER_OBJ;
  513.     newaclbufp->a_id = 0;
  514.     }
  515.  
  516.  newaclbufp->a_perm = 0;
  517.  
  518.  return 0;
  519. }
  520. #endif
  521.  
  522. /*****************************************************************************/
  523.  
  524. InstallACL(alias,classes)
  525.  
  526. char *alias, *classes;
  527.  
  528. { struct CFACL *ptr;
  529.  
  530.  Debug1("InstallACL(%s,%s)\n",alias,classes);
  531.  
  532.  if (! IsInstallable(classes))
  533.     {
  534.     Debug1("Not installing ACL no match\n");
  535.     return;
  536.     }
  537.  
  538.  VBUFF[0]='\0';                         /* Expand any variables */
  539.  ExpandVarstring(alias,VBUFF,"");
  540.  
  541.  if ((ptr = (struct CFACL *)malloc(sizeof(struct CFACL))) == NULL)
  542.     {
  543.     FatalError("Memory Allocation failed for InstallACL() #1");
  544.     }
  545.  
  546.  if ((ptr->acl_alias = strdup(VBUFF)) == NULL)
  547.     {
  548.     FatalError("Memory Allocation failed for InstallEditFile() #2");
  549.     }
  550.  
  551.  if (VACLLISTTOP == NULL)                 /* First element in the list */
  552.     {
  553.     VACLLIST = ptr;
  554.     }
  555.  else
  556.     {
  557.     VACLLISTTOP->next = ptr;
  558.     }
  559.  
  560.  ptr->aces = NULL;
  561.  ptr->next = NULL;
  562.  ptr->method = 'o';
  563.  ptr->type = StringToFstype("none"); 
  564.  VACLLISTTOP = ptr;
  565. }
  566.  
  567. /****** Code added for NT by J°rgen Kjensli & Bj°rn Gustafson, May 1999 *****/
  568.  
  569. #ifdef NT
  570.  
  571. DWORD
  572. getNTModeMask(new_mode, old_mode)
  573. char *new_mode;     /* The desired mode */
  574. DWORD old_mode;     /* The old access mask */
  575. {
  576.     /* Declare and initialize variables */
  577.     char *a;               /* Character to iterate the mode with */
  578.     enum {add, del} o;     /* Flag saying whether to add or remove rights */
  579.     DWORD accessMask;      /* Variable to hold the final mask */
  580.     o = add;               /* Start function with raised flag */
  581.     accessMask = old_mode; /* Initilaize the mask to the original/old mask */
  582.  
  583.     /* modetype: noaccess, default, all, change, read, rwxdop */
  584.  
  585.     /* No access. Should never get here (noaccess => all and denied ACE).
  586.        If it does get here, return the old mask (nothing is done) */
  587.     if (strcmp(new_mode, "noaccess") == 0)
  588.     {
  589.         Debug2("Setting ACE-mode to old_mode: %x\n",old_mode);
  590.         return (old_mode);
  591.     }
  592.  
  593.     /* Default - remove ACE. Set mask to 0 */
  594.     if (strcmp(new_mode, "default") == 0)
  595.     {
  596.         Verbose("Mode was default.\n");
  597.         Debug2("Setting ACE-mode to 0\n");
  598.         return (0);
  599.     }
  600.  
  601.     /* All. Return the NT's predefined bit mask for all rights */
  602.     if (strcmp(new_mode, "all") == 0)
  603.     {
  604.         Debug2("Setting ACE-mode to GENERIC_ALL: %d\n",GENERIC_ALL);
  605.         return (GENERIC_ALL);
  606.     }
  607.  
  608.     /* Change. Return the "rwxd" rights ORed with the existing mask */
  609.     if (strcmp(new_mode, "change") == 0)
  610.     {
  611.         Debug2("Setting ACE-mode to CHANGE: %d\n",(old_mode | GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | DELETE));
  612.         return (old_mode | GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | DELETE);
  613.     }
  614.  
  615.     /* Read. Return the "rx" rights ORed with the existing mask */
  616.     if (strcmp(new_mode, "read") == 0)
  617.     {
  618.         Debug2("Setting ACE-mode to READ: %d\n",(old_mode | GENERIC_READ | GENERIC_EXECUTE));
  619.         return (old_mode | GENERIC_READ | GENERIC_EXECUTE);
  620.     }
  621.  
  622.     /* If the code gets here we must treat the string character by character
  623.        We cannot remove rights if NT's predefined bit mask for all rights is
  624.        used. Translate this mask to a mask containing all rights (rwxdop) */
  625.     if (accessMask == GENERIC_ALL)
  626.     {
  627.         accessMask = (0x120089 | 0x120116 | 0x1200A0 | DELETE | WRITE_OWNER | WRITE_DAC);
  628.     }
  629.  
  630.     /* Iterate string with desired mode. Check each character */
  631.     for (a = new_mode; *a != '\0' ; *a++)
  632.     {
  633.         /* Decide wheteher to add or subtract permission bits */
  634.         if (*a == '+' || *a == ',')
  635.         {
  636.             o = add;
  637.         }
  638.         /* If equal sign, throw away old mask. Get ready to add permissions */
  639.         else if (*a == '=')
  640.         {
  641.             o = add;
  642.             accessMask = 0;
  643.         }
  644.         else if (*a == '-')
  645.         {
  646.             /* Prevent subtracting rights from user with no rights */
  647.             if (accessMask == 0)
  648.             {
  649.                 /* Return the old, original mask. Nothing is changed */
  650.                 return old_mode;
  651.             }
  652.             o = del;
  653.         }
  654.  
  655.         /* Character was a 'permission' character. Check which permission
  656.            and manipulate the mask */
  657.         else
  658.         {
  659.             /* Check permission bits and set accessMask */
  660.             switch (*a)
  661.             {
  662.                 case 'r':
  663.                     if (o == add)
  664.                     {
  665.                         /* Adding read rights */
  666.                         Debug2("Setting ACE-mode to READ.\n");
  667.                         accessMask |= 0x120089;
  668.                     }
  669.                     else
  670.                     {
  671.                         /* Removing read rights */
  672.                         Debug2("Removing READ from ACE-mode\n");
  673.  
  674.                         /* Execute allready set in mask. Remove relevant read-bits. */
  675.                         if ((accessMask & 0x1200A0) == 0x1200A0)
  676.                         {
  677.                             accessMask &= 0xFFFFF6;
  678.                         }
  679.                         /* Write is allready set in mask. Remove relevant read-bits. */
  680.                         else if ((accessMask & 0x120116) == 0x120116)
  681.                         {
  682.                             accessMask &= 0xFFFF76;
  683.                         }
  684.                         /* Neither write nor execute is set. Remove relevant read-bits. */
  685.                         else
  686.                         {
  687.                             accessMask &= 0xEDFF76;
  688.                         }
  689.                     }
  690.                     break;
  691.                 case 'w':
  692.                     if (o == add)
  693.                     {
  694.                         /* Adding write rights */
  695.                         Debug2("Setting ACE-mode to WRITE.\n");
  696.                         accessMask |= 0x120116;
  697.                     }
  698.                     else
  699.                     {
  700.                         /* Removing write rights */
  701.                         Debug2("Removing WRITE from ACE-mode\n");
  702.  
  703.                         Verbose("Old mask: %x\n",accessMask);
  704.  
  705.                         /* Execute or read is already set in mask. Remove relevant write-bits. */
  706.                         if (((accessMask & 0x120089) == 0x120089) || ((accessMask & 0x1200A0) == 0x1200A0))
  707.                         {
  708.                             accessMask &= 0xFFFEE9;
  709.                         }
  710.                         /* Neither read nor execute is set. Remove relevant write-bits. */
  711.                         else
  712.                         {
  713.                             accessMask &= 0xEDFEE9;
  714.                         }
  715.                     }
  716.                     break;
  717.                 case 'x':
  718.                     if (o == add)
  719.                     {
  720.                         /* Adding execute rights */
  721.                         Debug2("Setting ACE-mode to EXECUTE.\n");
  722.                         accessMask |= 0x1200A0;
  723.                     }
  724.                     else
  725.                     {
  726.                         /* Removing execute rights */
  727.                         Debug2("Removing EXECUTE from ACE-mode\n");
  728.  
  729.                         /* Read allready set in mask. Remove relevant execute-bits. */
  730.                         if ((accessMask & 0x120089) == 0x120089)
  731.                         {
  732.                             accessMask &= 0xFFFFDF;
  733.                         }
  734.                         /* Write is allready set in mask. Remove relevant execute-bits. */
  735.                         else if ((accessMask & 0x120116) == 0x120116)
  736.                         {
  737.                             accessMask &= 0xFFFF5F;
  738.                         }
  739.                         /* Neither write nor read is set. Remove relevant execute-bits. */
  740.                         else
  741.                         {
  742.                             accessMask &= 0xEDFF5F;
  743.                         }
  744.                     }
  745.                     break;
  746.                 case 'd':
  747.                     if (o == add)
  748.                     {
  749.                         /* Adding delete rights */
  750.                         Debug2("Setting ACE-mode to DELETE: %d\n",DELETE);
  751.                         accessMask |= DELETE;
  752.                     }
  753.                     else
  754.                     {
  755.                         /* Removing delete rights */
  756.                         Debug2("Setting ACE-mode to ~DELETE: %d\n",~DELETE);
  757.                         accessMask &= ~DELETE;
  758.                     }
  759.                     break;
  760.                 case 'o':
  761.                     if (o == add)
  762.                     {
  763.                         /* Adding owner rights */
  764.                         Debug2("Setting ACE-mode to WRITE_OWNER: %d\n",WRITE_OWNER);
  765.                         accessMask |= WRITE_OWNER;
  766.                     }
  767.                     else
  768.                     {
  769.                         /* Removing owner rights */
  770.                         Debug2("Setting ACE-mode to ~WRITE_OWNER: %d\n",~WRITE_OWNER);
  771.                         accessMask &= ~WRITE_OWNER;
  772.                     }
  773.                     break;
  774.                 case 'p':
  775.                     if (o == add)
  776.                     {
  777.                         /* Adding "change permission" rights */
  778.                         Debug2("Setting ACE-mode to WRITE_DAC: %d\n",WRITE_DAC);
  779.                         accessMask |= WRITE_DAC;
  780.                     }
  781.                     else
  782.                     {
  783.                         /* Removing "change permission" rights */
  784.                         Debug2("Setting ACE-mode to ~WRITE_DAC: %d\n",~WRITE_DAC);
  785.                         accessMask &= ~WRITE_DAC;
  786.                     }
  787.                     break;
  788.                 default:
  789.                     /* The character was not a valid permission */
  790.                     sprintf(OUTPUT,"Invalid mode string in NT acl: %s. No changes made.\n", new_mode);
  791.                     CfLog(cferror,OUTPUT,"");
  792.                     return old_mode;
  793.                            }
  794.         }
  795.     }
  796.  
  797.     /* Make sure the standard "ALL" is returned instead of RWXDOP. This is
  798.        done so that "All" is showed in NT's GUI */
  799.     if (accessMask == (0x120089 | 0x120116 | 0x1200A0 | DELETE | WRITE_OWNER | WRITE_DAC))
  800.     {
  801.         return (GENERIC_ALL);
  802.     }
  803.  
  804.     /* Return the new mask */
  805.     return (accessMask);
  806. }
  807.  
  808. #endif
  809.  
  810. /*************************** END NT Addition *******************************/
  811.  
  812. AddACE(acl,string,classes)
  813.  
  814. char *acl, *string, *classes;
  815.  
  816. { struct CFACL *ptr;
  817.  struct CFACE *new, *top;
  818.  char varbuff[bufsize], *cp;
  819.  char comm[maxvarsize],data1[maxvarsize],data2[maxvarsize];
  820. /****** Code added for NT by J°rgen Kjensli & Bj°rn Gustafson, May 1999 *****/
  821.  
  822.  char data3[maxvarsize];     /* To hold the extra variable accesstype */
  823.  
  824. /*************************** END NT Addition *******************************/
  825.  int i;
  826.  
  827.  Debug1("AddACE(%s,%s,[%s])\n",acl,string,classes);
  828.  
  829.  if ( ! IsInstallable(CLASSBUFF))
  830.     {
  831.     Debug1("Not installing ACE no match\n");
  832.     return;
  833.     }
  834.  
  835.  for (ptr = VACLLIST; ptr != NULL; ptr=ptr->next)
  836.     {
  837.     varbuff[0] = '\0';
  838.     ExpandVarstring(acl,varbuff,"");
  839.  
  840.     if (strcmp(ptr->acl_alias,varbuff) == 0)
  841.        {
  842.        comm[0] = data1[0] = data2[0] = '\0';
  843.  
  844. /****** Code added for NT by J°rgen Kjensli & Bj°rn Gustafson, May 1999 *****/
  845.  
  846.        data3[0] = '\0';      /* Initialize variable */
  847.  
  848. /*************************** END NT Addition *******************************/
  849.  
  850.        if ((new = (struct CFACE *)calloc(1,sizeof(struct CFACE))) == NULL)
  851.       {
  852.       FatalError("Memory Allocation failed for AddEditAction() #1");
  853.       }
  854.  
  855.        if (ptr->aces == NULL)
  856.       {
  857.       ptr->aces = new;
  858.       }
  859.        else
  860.       {
  861.       for (top = ptr->aces; top->next != NULL; top=top->next)
  862.          {
  863.          }
  864.       top->next = new;
  865.       new->next = NULL;
  866.       }
  867.  
  868.        if (string == NULL)
  869.       {
  870.       new->name = NULL;
  871.       new->next = NULL;
  872.       }
  873.        else
  874.       {
  875.       bzero(VBUFF, sizeof(VBUFF));
  876.       VBUFF[0]='\0';                         /* Expand any variables */
  877.       ExpandVarstring(string,VBUFF,"");
  878.  
  879.       cp = VBUFF;
  880.       i = 0;
  881.       while (*cp != ':' && *cp != '\0') {
  882.       comm[i++] = *cp++;
  883.       }
  884.       comm[i] = 0;
  885.       *cp++;
  886.  
  887.       i = 0;
  888.       while (*cp != ':' && *cp != '\0') {
  889.       data1[i++] = *cp++;
  890.       }
  891.       data1[i] = 0;
  892.       *cp++;
  893.  
  894.       i = 0;
  895.       while (*cp != ':' && *cp != '\0') {
  896.       data2[i++] = *cp++;
  897.       }
  898.       data2[i] = 0;
  899.  
  900. /****** Code added for NT by J°rgen Kjensli & Bj°rn Gustafson, May 1999 *****/
  901.  
  902.       /* Parse the string to get the access type */
  903.       #ifdef NT
  904.       *cp++;
  905.       i = 0;
  906.       while (*cp != ':' && *cp != '\0') {
  907.       data3[i++] = *cp++;
  908.       }
  909.       data3[i] = 0;
  910.       #endif
  911.  
  912. /*************************** END NT Addition *******************************/
  913.  
  914.       if (strncmp("fstype",comm,strlen(comm)) == 0)
  915.          {
  916.          ptr->type = StringToFstype(data1);
  917.          new->next = NULL;
  918.          return;
  919.          }
  920.  
  921.       if (strncmp("method",comm,strlen(comm)) == 0)
  922.          {
  923.          ptr->method = ToLower(*data1);
  924.          new->next = NULL;
  925.          return;
  926.          }
  927.  
  928.       if ((new->acltype = strdup(comm)) == NULL)
  929.          {
  930.          FatalError("Memory Allocation failed for AddACE() #1");
  931.          }
  932.  
  933.       if ((new->name = strdup(data1)) == NULL)
  934.          {
  935.          FatalError("Memory Allocation failed for AddACE() #2");
  936.          }
  937.  
  938. /****** Code added for NT by J°rgen Kjensli & Bj°rn Gustafson, May 1999 *****/
  939.       #ifdef NT
  940.  
  941.       /* Give all users defined in config file a default mask of 0 */
  942.       new->NTMode = 0;
  943.  
  944.       /* If "noaccess" is the specified permission, store the permission
  945.          "all" on an access denied ACE to get the wanted effect of "No Access"
  946.          showed in NT's GUI */
  947.       if (strcmp(data2,"noaccess") == 0)
  948.       {
  949.           if ((new->mode = strdup("all")) == NULL)
  950.           {
  951.              FatalError("Memory Allocation failed for AddACE() #2");
  952.           }
  953.           if ((new->access = strdup("denied")) == NULL)
  954.           {
  955.              FatalError("Memory Allocation failed for AddACE() #3");
  956.           }
  957.       }
  958.       /* Unless "noaccess" is specified, store the specified values as usual */
  959.       else
  960.       {
  961.           if ((new->mode = strdup(data2)) == NULL)
  962.           {
  963.             FatalError("Memory Allocation failed for AddACE() #2");
  964.           }
  965.           if ((new->access = strdup(data3)) == NULL)
  966.           {
  967.              FatalError("Memory Allocation failed for AddACE() #3");
  968.           }
  969.       }
  970.       #else
  971. /*************************** END NT Addition *******************************/
  972.       if ((new->mode = strdup(data2)) == NULL)
  973.          {
  974.          FatalError("Memory Allocation failed for AddACE() #2");
  975.          }
  976.       #endif
  977.       }
  978.  
  979.        if ((new->classes = strdup(classes)) == NULL)
  980.       {
  981.       FatalError("Memory Allocation failed for InstallEditFile() #3");
  982.       }
  983.        return;
  984.        }
  985.     }
  986.  
  987.  printf("cfengine: software error - no ACL matched installing %s \n",acl);
  988. }
  989.  
  990. /*****************************************************************************/
  991.  
  992. CheckACLs(filename,action,acl_aliases)
  993.  
  994. char *filename;
  995. enum fileactions action;
  996. struct Item *acl_aliases;
  997.  
  998. { struct Item *ip;
  999.  struct CFACL *ap;
  1000.  int status = false;
  1001.  
  1002.  Debug1("CheckACLs(%s)\n",filename);
  1003.  
  1004.  for (ip = acl_aliases; ip != NULL; ip = ip->next)
  1005.     {
  1006.     if ((ap = GetACL(ip->name)) != NULL)
  1007.        {
  1008.        Verbose(" ACL method (overwrite/append) = %c on %s\n",ap->method,filename);
  1009.  
  1010.        switch(ap->type)
  1011.       {
  1012.       case solarisfs:
  1013.       case posixfs:
  1014.           status = CheckPosixACE(ap->aces,ap->method,filename,action);
  1015.           break;
  1016.       case dfsfs:
  1017.           status = CheckDFSACE(ap->aces,ap->method,filename,action);
  1018.           break;
  1019. /****** Code added for NT by J°rgen Kjensli & Bj°rn Gustafson, May 1999 *****/
  1020.       case ntfs:
  1021.           /* The nt filesystem is defined. Call our function to implement
  1022.              the ACLs on NT. */
  1023.           status = CheckNTACE(ap->aces,ap->method,filename,action);
  1024.           break;
  1025. /*************************** END NT Addition *******************************/
  1026.       default:
  1027.           sprintf("Unknown filesystem type in ACL %s\n",ip->name);
  1028.           CfLog(cferror,OUTPUT,"");
  1029.       }
  1030.        }
  1031.     else
  1032.        {
  1033.        Verbose("ACL %s does not exist (file=%s)\n",ip->name,filename);
  1034.        }
  1035.     }
  1036.  return status;
  1037. }
  1038.  
  1039.  
  1040. /*****************************************************************************/
  1041. /* Level 2                                                                   */
  1042. /*****************************************************************************/
  1043.  
  1044. enum cffstype StringToFstype(string)
  1045.  
  1046. char *string;
  1047.  
  1048. { int i;
  1049.  
  1050.  for (i = 0; CFFSTYPES[i] != NULL; i++)
  1051.     {
  1052.     if (strcmp(string,CFFSTYPES[i]) == 0)
  1053.        {
  1054.        return (enum cffstype) i;
  1055.        }
  1056.     }
  1057.  
  1058.  return (enum cffstype) i;
  1059. }
  1060.  
  1061. /*****************************************************************************/
  1062.  
  1063. struct CFACL *GetACL(acl_alias)
  1064.  
  1065. char *acl_alias;
  1066.  
  1067. { struct CFACL *ap;
  1068.  
  1069.  for (ap = VACLLIST; ap != NULL; ap = ap->next)
  1070.     {
  1071.     if (strcmp(acl_alias,ap->acl_alias) == 0)
  1072.        {
  1073.        return ap;
  1074.        }
  1075.     }
  1076.  
  1077.  return NULL;
  1078. }
  1079.  
  1080. /****** Code added for NT by J°rgen Kjensli & Bj°rn Gustafson, May 1999 *****/
  1081.  
  1082. #ifdef NT
  1083.  
  1084. DWORD
  1085. getNTACEs_Size(aces)
  1086. struct CFACE *aces; /* List of CFACEs */
  1087. {
  1088.     /* Declarations */
  1089.     struct CFACE *ep;       /* Pointer to a CFACE struct. To iterate through
  1090.                                the existing list (received as parameter)  */
  1091.     DWORD sidSize = 256;    /* The maximum size of the users SID          */
  1092.     DWORD domainSize = 256; /* The maximum size of the name of the domain */
  1093.     char domain[256];        /* Allocate max memory for the domain name    */
  1094.     PSID psid;                /* A pointer to a security identifier (SID)   */
  1095.     SID_NAME_USE snu;       /* Enumerated type indicating type of account */
  1096.     DWORD totalACESize = 0; /* Total accumulated size of all ACEs in list */
  1097.     DWORD accessSize = 0;   /* Variable to hold the size of the ACE       */
  1098.     DWORD psidSize = 0;     /* Variable to hold the size of the SID       */
  1099.  
  1100.     /* Iterate through every CFACE in the list sent to the function */
  1101.     for (ep = aces; ep != NULL; ep=ep->next)
  1102.     {
  1103.         /* Do not count ACE if name is null or if class is excluded or
  1104.            if mode is "default"*/
  1105.         if ((ep->name == NULL) || (IsExcluded(ep->classes)) || (strcmp(ep->mode,"default") == 0))
  1106.         {
  1107.             continue;
  1108.         }
  1109.  
  1110.         /* Finding size of SID */
  1111.         sidSize = 0;
  1112.         domainSize = 256;
  1113.         LookupAccountName(NULL, ep->name, NULL, &sidSize, domain, &domainSize, &snu);
  1114.  
  1115.         /* If SID doesn't exist, continue loop */
  1116.         if (!sidSize)
  1117.         {
  1118.             continue;
  1119.         }
  1120.  
  1121.         /* Reset accessSize and get the size of the ACE */
  1122.         accessSize = 0;
  1123.         if ((strcmp(ep->access,"allowed") == 0) || (ep->access == '\0'))
  1124.         {
  1125.             accessSize = sizeof(ACCESS_ALLOWED_ACE);
  1126.         }
  1127.         else if (strcmp(ep->access,"denied") == 0)
  1128.         {
  1129.             accessSize = sizeof(ACCESS_DENIED_ACE);
  1130.         }
  1131.  
  1132.         /* Finally add up the size of the sid, the accesstype, and subtract a DWORD.
  1133.            We subtract a DWORD because the ACE size by default contains one DWORD
  1134.            while we know the exact size of it (sidBufferSize) */
  1135.         totalACESize += (sidSize + accessSize - sizeof(DWORD));
  1136.     }
  1137.  
  1138.     /* Return the total size of all ACEs */
  1139.     return totalACESize;
  1140. }
  1141.  
  1142. #endif
  1143.  
  1144. /*****************************************************************************/
  1145.  
  1146. #ifdef NT
  1147.  
  1148. SECURITY_DESCRIPTOR*
  1149. getNTACLInformation(filename, old_pacl, haveACL, oldACLSize)
  1150. char *filename;  /* The name of the file */
  1151. PACL *old_pacl;  /* Pointer to an ACL */
  1152. BOOL *haveACL;   /* Flag to say wheteher ACL exists or not */
  1153. ACL_SIZE_INFORMATION *oldACLSize; /*Pointer to a struct with info about ACL*/
  1154. {
  1155.     DWORD sizeRqd;        /* Size needed to hold the file's SD */
  1156.     DWORD old_sdSize;   /* Size needed to hold the SD */
  1157.     SECURITY_DESCRIPTOR *old_sd; /* Pointer to a SD */
  1158.     BOOL byDef;            /* Flag needed for a function call */
  1159.  
  1160.     /* Find the size of the old security descriptor */
  1161.     sizeRqd = 0;
  1162.     GetFileSecurity(filename, DACL_SECURITY_INFORMATION, NULL, 0, &sizeRqd);
  1163.  
  1164.     if (sizeRqd == 0)
  1165.     {
  1166.         sprintf(OUTPUT,"%s: acl: Unable to get size of old SD\n", VPREFIX);
  1167.         CfLog(cferror,OUTPUT,"");
  1168.         return;
  1169.     }
  1170.  
  1171.     /* Allocate memory for the old security descriptor */
  1172.     if ((old_sd = (SECURITY_DESCRIPTOR *) malloc(sizeRqd)) == NULL)
  1173.     {
  1174.         sprintf(OUTPUT,"%s: acl: Unable to allocate memory for the old SD\n", VPREFIX);
  1175.         CfLog(cferror,OUTPUT,"");
  1176.         return;
  1177.     }
  1178.  
  1179.     /* Retrieve the old security descriptor */
  1180.     old_sdSize = sizeRqd;
  1181.     if (!GetFileSecurity(filename, DACL_SECURITY_INFORMATION, old_sd, old_sdSize, &sizeRqd))
  1182.     {
  1183.         sprintf(OUTPUT,"%s: acl: Unable to get the old SD\n", VPREFIX);
  1184.         CfLog(cferror,OUTPUT,"");
  1185.         return;
  1186.     }
  1187.  
  1188.     /* Retrieve information about the old security descriptor */
  1189.     if (!GetSecurityDescriptorDacl(old_sd, haveACL, old_pacl, &byDef))
  1190.     {
  1191.         sprintf(OUTPUT,"%s: acl: Unable to get information about the old SD\n", VPREFIX);
  1192.         CfLog(cferror,OUTPUT,"");
  1193.         return;
  1194.     }
  1195.  
  1196.     /* File did have an ACL */
  1197.     if (*haveACL)
  1198.     {
  1199.         /* Retrieve size information about the old ACL and add it to the size of the new */
  1200.         if (!GetAclInformation(*old_pacl, oldACLSize, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation))
  1201.         {
  1202.             sprintf(OUTPUT,"%s: acl: Unable to get information about the old ACL\n", VPREFIX);
  1203.             CfLog(cferror,OUTPUT,"");
  1204.             return;
  1205.         }
  1206.     }
  1207.     else
  1208.     {
  1209.         sprintf(OUTPUT,"%s: acl: The old security descriptor does not contain an ACL\n", VPREFIX);
  1210.         CfLog(cferror,OUTPUT,"");
  1211.         return;
  1212.     }
  1213.  
  1214.     return old_sd;
  1215. }
  1216.  
  1217. #endif
  1218.  
  1219. /*****************************************************************************/
  1220.  
  1221. #ifdef NT
  1222.  
  1223. attachToNTACEs(new_aces, user, mode, access, classes, NTMask)
  1224. struct CFACE *new_aces; /* Pointer to an empty list of CFACEs */
  1225. char *user;                /* Name of user */
  1226. char *mode;                /* User's mode */
  1227. char *access;           /* User's type of access */
  1228. char *classes;            /* Class */
  1229. DWORD NTMask;            /* User's accessmask */
  1230. {
  1231.     /* Declaration of variables */
  1232.     struct CFACE *newACE; /* Pointer to a CFACE to hold new information */
  1233.     struct CFACE *ep;      /* Pointer to a CFACE. To iterate through list */
  1234.  
  1235.     /* Check if mode was default i.e. NTMask = 0 */
  1236.     if (NTMask == 0)
  1237.     {
  1238.         return;
  1239.     }
  1240.  
  1241.     /* Allocate memory for new ACE */
  1242.     if ((newACE = (struct CFACE *)malloc(sizeof(struct CFACE))) == NULL)
  1243.     {
  1244.         FatalError("Memory Allocation failed for AddEditAction() #1");
  1245.     }
  1246.  
  1247.     /* Hook the new ACE to the end list */
  1248.     if (new_aces == NULL)
  1249.     {
  1250.         new_aces = newACE;
  1251.     }
  1252.     else
  1253.     {
  1254.         for (ep = new_aces; ep->next != NULL; ep=ep->next)
  1255.         {
  1256.         }
  1257.         ep->next = newACE;
  1258.     }
  1259.     newACE->next = NULL;
  1260.  
  1261.     /* Set the values of the new ACE */
  1262.     if ((newACE->name = strdup(user)) == NULL)
  1263.     {
  1264.         FatalError("Memory Allocation failed for name-member.");
  1265.     }
  1266.     if ((newACE->mode = strdup(mode)) == NULL)
  1267.     {
  1268.         FatalError("Memory Allocation failed for mode-member.");
  1269.     }
  1270.     if ((newACE->access = strdup(access)) == NULL)
  1271.     {
  1272.         FatalError("Memory Allocation failed for access-member.");
  1273.     }
  1274.     if ((newACE->classes = strdup(classes)) == NULL)
  1275.     {
  1276.         FatalError("Memory Allocation failed for classes-member.");
  1277.     }
  1278.     newACE->NTMode = NTMask;
  1279. }
  1280.  
  1281. #endif
  1282.  
  1283. /*****************************************************************************/
  1284.  
  1285. #ifdef NT
  1286.  
  1287. appendNTACEs(aces, new_aces, oldACLSize, old_pacl)
  1288. struct CFACE *aces;             /* List of CFACEs */
  1289. struct CFACE *new_aces;         /* List of CFACEs */
  1290. ACL_SIZE_INFORMATION oldACLSize;/* Will hold info about the file's ACL */
  1291. PACL old_pacl;                  /* Pointer to an ACL */
  1292. {
  1293.     int x;                        /* Counter */
  1294.     struct CFACE *ep;           /* Pointer to CFACE. For iteration purposes */
  1295.     ACCESS_ALLOWED_ACE *aceType;/* A Pointer to an ACE */
  1296.     SID_NAME_USE sidType;       /* Indicating type of account*/
  1297.     char user[256];             /* Buffer to hold username */
  1298.     char domain[256];            /* Buffer to hold domain name */
  1299.     DWORD uLength = 256;        /* Maximum length of username */
  1300.     DWORD dLength = 256;        /* Maximum length of domain name */
  1301.     DWORD NTMode = 0;
  1302.  
  1303.     Verbose("Existing users: %d\n",oldACLSize.AceCount);
  1304.  
  1305.     /* Iterate through all existing ACEs */
  1306.     for (x = 0; x < oldACLSize.AceCount; x++)
  1307.     {
  1308.         /* Get ace information */
  1309.         if (GetAce(old_pacl, x, (LPVOID *) &aceType))
  1310.         {
  1311.             /* Reset maximum lengths and check that the user exists */
  1312.             uLength = dLength = 256;
  1313.             if (!LookupAccountSid(NULL, (PSID)(&aceType->SidStart), user, &uLength, domain, &dLength, &sidType))
  1314.             {
  1315.                 sprintf(OUTPUT,"%s: acl: Unable to get allowed ACE's username\n", VPREFIX);
  1316.                 CfLog(cferror,OUTPUT,"");
  1317.                 continue;
  1318.             }
  1319.  
  1320.             /* Remember the existing ACEs mask */
  1321.             NTMode = aceType->Mask;
  1322.  
  1323.             /* If user allready exists in our old CFACE list, give him a new mask */
  1324.             for (ep = aces; ep != NULL; ep=ep->next)
  1325.             {
  1326.                 /* Skip ACE if name is null or if class is excluded or if mode is "default"*/
  1327.                 if ((ep->name == NULL) || (IsExcluded(ep->classes)))
  1328.                 {
  1329.                     continue;
  1330.                 }
  1331.  
  1332.                 /* If user is listed in config file with access allowed, and existing
  1333.                     ACE-type is also allowed, or user is listed in config file with
  1334.                     access denied, and existing ACE-type is also denied, then find
  1335.                     new updated and proper NTModeMask for that user*/
  1336.                 if (strcmp(ep->name,user) == 0)
  1337.                 {
  1338.                     if (((strcmp(ep->access,"allowed") == 0) && ((aceType->Header.AceType) == ACCESS_ALLOWED_ACE_TYPE)) ||
  1339.                        ((strcmp(ep->access,"denied") == 0) && ((aceType->Header.AceType) == ACCESS_DENIED_ACE_TYPE)))
  1340.                     {
  1341.                         /* Get new mask (combination of old mask and new mode) */
  1342.                         ep->NTMode = NTMode = getNTModeMask(ep->mode,aceType->Mask);
  1343.                         break;
  1344.                     }
  1345.                 }
  1346.             }
  1347.  
  1348.             /* User didn't exist in config file. NTMode has the ACEs mask then.
  1349.                Attach the user to our new list */
  1350.             if ((aceType->Header.AceType) == ACCESS_ALLOWED_ACE_TYPE)
  1351.             {
  1352.                 Debug1("Attaching allowed ace for %s with mask: %x\n",user,NTMode);
  1353.                 attachToNTACEs(new_aces, user, "", "allowed", "any", NTMode);
  1354.             }
  1355.             else if ((aceType->Header.AceType) == ACCESS_DENIED_ACE_TYPE)
  1356.             {
  1357.                 Debug1("Attaching denied ace for %s with mask: %x\n",user,NTMode);
  1358.                 attachToNTACEs(new_aces, user, "", "denied", "any", NTMode);
  1359.             }
  1360.             else
  1361.             {
  1362.                 sprintf(OUTPUT,"%s: acl: Existing ACE lost due to it's unfamiliar ACE type(#%x) (allowed=0, denied=1)\n", VPREFIX,(aceType->Header.AceType));
  1363.                 CfLog(cferror,OUTPUT,"");
  1364.             }
  1365.         }
  1366.  
  1367.         /* Unable to get old ACE */
  1368.         else
  1369.         {
  1370.             printf("Unable to get ACE.\n");
  1371.             continue;
  1372.         }
  1373.     }
  1374. }
  1375.  
  1376. #endif
  1377.  
  1378. /*****************************************************************************/
  1379.  
  1380. #ifdef NT
  1381.  
  1382. AddNTACEs(accessType,new_aces,new_pacl)
  1383. char *accessType;       /* type of ACEs to add (allowed/denied) */
  1384. struct CFACE *new_aces; /* List of ACEs to check for the accesstype*/
  1385. PACL *new_pacl;            /* Pointer to the ACL that shoul be altered */
  1386. {
  1387.     /* Declarations of variables */
  1388.     struct CFACE *ep;   /* To iterate through list of CFACEs */
  1389.     PSID psid;            /* Pointer to a SID */
  1390.     DWORD sidSize;      /* To hold size of SID */
  1391.     char domain[256];    /* Buffer to hold domain name */
  1392.     DWORD domainSize=256;/*Maximum size of domain */
  1393.     SID_NAME_USE snu;    /* Indicating type of account*/
  1394.     int counter = -1;   /* Counter for verbose reasons */
  1395.  
  1396.     Verbose("---------------------- ACE info-------------------------------\n");
  1397.  
  1398.     /* Iterate through list of CFACEs */
  1399.     for (ep = new_aces; ep != NULL; ep=ep->next)
  1400.     {
  1401.         counter++;
  1402.  
  1403.         /* Do not create ACE if name is null or if class is excluded or if mode is "default"*/
  1404.         if ((ep->name == NULL) || (IsExcluded(ep->classes)) || (ep->NTMode == 0) || (strcmp(ep->mode,"default") == 0))
  1405.         {
  1406.             continue;
  1407.         }
  1408.  
  1409.         /* Finding size of SID */
  1410.         sidSize = 0;
  1411.         domainSize = 256;
  1412.         LookupAccountName(NULL, ep->name, NULL, &sidSize, domain, &domainSize, &snu);
  1413.  
  1414.         /* If SID doesn't exist, continue loop */
  1415.         if (!sidSize)
  1416.         {
  1417.             sprintf(OUTPUT,"%s: acl: User %s doesn't exist. ACE not created.\n", VPREFIX, ep->name);
  1418.             CfLog(cferror,OUTPUT,"");
  1419.             continue;
  1420.         }
  1421.  
  1422.         /* Allocate memory for list with new ACEs */
  1423.         if ((psid = (PSID)malloc(sidSize)) == NULL)
  1424.         {
  1425.             FatalError("Memory Allocation failed for SID\n");
  1426.         }
  1427.  
  1428.         /* Reset buffersize, get the SID and create ACE if user or group exists */
  1429.         domainSize = 256;
  1430.         if (!LookupAccountName(NULL, ep->name, psid, &sidSize, domain, &domainSize, &snu))
  1431.         {
  1432.             sprintf(OUTPUT,"%s: acl: User doesn't exist. Will not create ACE for: %s\n", VPREFIX, ep->name);
  1433.             CfLog(cferror,OUTPUT,"");
  1434.             free(psid);
  1435.             continue;
  1436.         }
  1437.  
  1438.         /* Check accesstype and add either an Access Denied or Allowed ACE. */
  1439.         if ((strcmp(accessType,"denied") == 0) && (strcmp(ep->access,"denied") == 0))
  1440.         {
  1441.             if (!AddAccessDeniedAce(*new_pacl, ACL_REVISION, ep->NTMode, psid))
  1442.             {
  1443.                 sprintf(OUTPUT,"%s: acl: Unable to add new denied ACE for user %s\n", VPREFIX, ep->name);
  1444.                 CfLog(cferror,OUTPUT,"");
  1445.                 free(psid);
  1446.                 return;
  1447.             }
  1448.             Debug2("- Ace #%d info:\n",counter);
  1449.             Debug2("          mode (permission flags) is    %x\n",ep->NTMode);
  1450.             Debug2("          name (id name) is             %s\n",ep->name);
  1451.             Debug2("          access type (allow/deny) is   %s\n",ep->access);
  1452.             Debug2("          classes is                    %s\n",ep->classes);
  1453.             Debug2("          ----------------------------------\n");
  1454.             Debug2("Adding access denied for user: %s\n\n",ep->name);
  1455.         }
  1456.         else if ((strcmp(accessType,"allowed") == 0) && ((strcmp(ep->access,"allowed") == 0) || (ep->access == '\0')))
  1457.         {
  1458.             if (!AddAccessAllowedAce(*new_pacl, ACL_REVISION, ep->NTMode, psid))
  1459.             {
  1460.                 sprintf(OUTPUT,"%s: acl: Unable to add new allowed ACE for user %s\n", VPREFIX, ep->name);
  1461.                 CfLog(cferror,OUTPUT,"");
  1462.                 free(psid);
  1463.                 return;
  1464.             }
  1465.             Debug2("- Ace #%d info:\n",counter);
  1466.             Debug2("          mode (permission flags) is    %x\n",ep->NTMode);
  1467.             Debug2("          name (id name) is             %s\n",ep->name);
  1468.             Debug2("          access type (allow/deny) is   %s\n",ep->access);
  1469.             Debug2("          classes is                    %s\n",ep->classes);
  1470.             Debug2("          ----------------------------------\n");
  1471.             Debug2("Adding access allowed for user: %s\n",ep->name);
  1472.         }
  1473.  
  1474.         /* Free memory */
  1475.         free(psid);
  1476.     }
  1477.     Verbose("----------------------end-------------------------------\n");
  1478. }
  1479.  
  1480. #endif
  1481.  
  1482. /*****************************************************************************/
  1483.  
  1484. #ifdef NT
  1485.  
  1486. createNTACL(aces, method, filename, action)
  1487. struct CFACE *aces;     /* List built up during parsing of config file */
  1488. char method;            /* ACL operation method (o/a) */
  1489. char *filename;            /* The filename */
  1490. enum fileactions action;/* The action to be performed */
  1491. {
  1492.     /* Declarations */
  1493.     struct CFACE *ep;        /* Pointer for iteration purposes */
  1494.     struct CFACE *new_aces;    /* Pointer to a new list of CFACEs */
  1495.     struct CFACE *temp_ace; /* Temporary pointer to iterate a list later */
  1496.     SECURITY_DESCRIPTOR *old_sd;/* Pointer to the file's old SD */
  1497.     SECURITY_ATTRIBUTES sa;        /* To hold security info */
  1498.     SECURITY_DESCRIPTOR sd;        /* Pointer to a new SD */
  1499.     PACL new_pacl;             /* Pointer to a new ACL */
  1500.     PACL old_pacl;            /* Pointer to the old ACL */
  1501.     DWORD newACLSize;        /* To hold the size of all the ACEs */
  1502.     BOOL haveACL;            /* Flag to say whether old ACL existed */
  1503.     ACL_SIZE_INFORMATION oldACLSize;    /* To hold inof about old ACL */
  1504.     ACL_SIZE_INFORMATION newACLSizeInfo;/* To hold inof about new ACL */
  1505.  
  1506.     /* Allocate memory for list with new ACEs */
  1507.     if ((new_aces = (struct CFACE *)calloc(1,sizeof(struct CFACE))) == NULL)
  1508.     {
  1509.         FatalError("Memory Allocation failed for new_aces\n");
  1510.     }
  1511.     new_aces->next = NULL;
  1512.  
  1513.     /* Get information about existing ACL if append method */
  1514.     if (method == 'a')
  1515.     {
  1516.         /* Get information about existing ACL */
  1517.         old_sd = getNTACLInformation(filename, &old_pacl, &haveACL, &oldACLSize);
  1518.         if (haveACL)
  1519.         {
  1520.             /* The file had an ACL. Append existing ACEs to our new list */
  1521.             appendNTACEs(aces, new_aces, oldACLSize, old_pacl);
  1522.         }
  1523.         else
  1524.         {
  1525.             Verbose("File: %s has no security descriptor (Unrestricted access)!!\n");
  1526.         }
  1527.     }
  1528.  
  1529.     /* All users from old ACL are added to our list with correct mask (if append).
  1530.        Users in our CFACE list with NTModeMask=0 are users that didn't exist before.
  1531.        Give them a proper mask */
  1532.     for (ep = aces; ep != NULL; ep=ep->next)
  1533.     {
  1534.         /* Skip ACE if name is null or if class is excluded or if mode is "default"*/
  1535.         if ((ep->name == NULL) || (IsExcluded(ep->classes)) || (strcmp(ep->mode,"default") == 0))
  1536.         {
  1537.             continue;
  1538.         }
  1539.  
  1540.         /* User has noNTModeMask. Give him one and attach him to our new list. */
  1541.         if (ep->NTMode == 0)
  1542.         {
  1543.             attachToNTACEs(new_aces, ep->name, ep->mode, ep->access, ep->classes, getNTModeMask(ep->mode,ep->NTMode));
  1544.         }
  1545.     }
  1546.  
  1547.     /* Get the size of all ACE's that will be inserted in the new ACL */
  1548.     if ((newACLSize = getNTACEs_Size(new_aces)) == 0)
  1549.     {
  1550.         sprintf(OUTPUT,"%s: acl: Size of ACEs is zero.\n", VPREFIX);
  1551.         CfLog(cferror,OUTPUT,"");
  1552.         return;
  1553.     }
  1554.  
  1555.     /* Add the size of an empty ACL */
  1556.     newACLSize += sizeof(ACL);
  1557.  
  1558.     /* Initialize a Security Descriptor for the new ACL*/
  1559.     if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
  1560.     {
  1561.         sprintf(OUTPUT,"%s: acl: Unable to init new SD\n", VPREFIX);
  1562.         CfLog(cferror,OUTPUT,"");
  1563.         return;
  1564.     }
  1565.  
  1566.     /* Allocate memory for the new ACL */
  1567.     if ((new_pacl = (PACL)calloc(1,newACLSize)) == NULL)
  1568.     {
  1569.         sprintf(OUTPUT,"%s: acl: Unable to allocate memory for new ACL\n", VPREFIX);
  1570.         CfLog(cferror,OUTPUT,"");
  1571.         return;
  1572.     }
  1573.  
  1574.     /* Initialize the new ACL */
  1575.     if (!InitializeAcl(new_pacl, newACLSize, ACL_REVISION))
  1576.     {
  1577.         sprintf(OUTPUT,"%s: acl: Unable to initialize the new ACL\n", VPREFIX);
  1578.         CfLog(cferror,OUTPUT,"");
  1579.         return;
  1580.     }
  1581.  
  1582.     /* Adding all denied aces first, then all allowed aces */
  1583.     AddNTACEs("denied",new_aces,&new_pacl);
  1584.     AddNTACEs("allowed",new_aces,&new_pacl);
  1585.  
  1586.     /* Set the new ACL into the Security Descriptor */
  1587.     if (!SetSecurityDescriptorDacl(&sd, TRUE, new_pacl, FALSE))
  1588.     {
  1589.         sprintf(OUTPUT,"%s: acl: Unable to install new ACL\n", VPREFIX);
  1590.         CfLog(cferror,OUTPUT,"");
  1591.         return;
  1592.     }
  1593.  
  1594.     /* Check the new Security Descriptor */
  1595.     if (!IsValidSecurityDescriptor(&sd))
  1596.     {
  1597.         sprintf(OUTPUT,"%s: acl: New Security Descriptor is invalid\n", VPREFIX);
  1598.         CfLog(cferror,OUTPUT,"");
  1599.         return;
  1600.     }
  1601.  
  1602.     /* Install new ACL and new Security Descriptor */
  1603.     if (!SetFileSecurity(filename, DACL_SECURITY_INFORMATION, &sd))
  1604.     {
  1605.         sprintf(OUTPUT,"%s: acl: Unable to set file security on file: %s\n", VPREFIX, filename);
  1606.         CfLog(cferror,OUTPUT,"");
  1607.         return;
  1608.     }
  1609.  
  1610.     /* Release memory */
  1611.     free(new_pacl);
  1612.     if (method == 'a')
  1613.     {
  1614.         free(old_sd);
  1615.     }
  1616.     ep = new_aces;
  1617.     while (ep != NULL)
  1618.     {
  1619.         temp_ace = ep;
  1620.         ep = ep->next;
  1621.         free(temp_ace);
  1622.     }
  1623.  
  1624.     Verbose("ACL installed successfully for file: %s\n",filename);
  1625. }
  1626.  
  1627. #endif
  1628.  
  1629. /*****************************************************************************/
  1630.  
  1631. CheckNTACE(aces,method,filename,action)
  1632. struct CFACE *aces;     /* List built up during parsing of config file */
  1633. char method;            /* ACL operation method (o/a) */
  1634. char *filename;            /* The filename */
  1635. enum fileactions action;/* The action to be performed */
  1636. {
  1637. #ifdef NT
  1638.  struct CFACE *ep;
  1639.  Debug2("\n------------------------ ACL info ---------------------------------\n");
  1640.  Debug2("- Filesystem is ntfs.\n");
  1641.  Debug2("- Filename is %s\n",filename);
  1642.  Debug2("- Method is %c\n",method);
  1643.  Debug2("- Action is element # %d of enum fileactions\n",action);
  1644.  
  1645.  /* Create the new ACL */
  1646.  createNTACL(aces, method, filename, action);
  1647.  
  1648.  return true;
  1649. #else
  1650.  Verbose("This system is not NT. Can't create ACLs on this system...\n");
  1651. #endif
  1652. }
  1653.  
  1654. /*************************** END NT Addition *******************************/
  1655.  
  1656. CheckPosixACE(aces,method,filename,action)
  1657. struct CFACE *aces;
  1658. char method;
  1659. char *filename;
  1660. enum fileactions action;
  1661. {
  1662. #if defined(HAVE_SYS_ACL_H) && defined(SOLARIS)
  1663.  struct CFACE *ep;
  1664.  aclent_t aclbufp[MAX_ACL_ENTRIES], newaclbufp[MAX_ACL_ENTRIES], tmpacl;
  1665.  int nacl = 0, newacls = 0, status = 0, update = 0, i, j;
  1666.  struct stat sb;
  1667.  uid_t myuid;
  1668.  
  1669.  bzero(aclbufp, sizeof(aclbufp));
  1670.  bzero(newaclbufp, sizeof(newaclbufp));
  1671.  nacl = acl (filename, GETACLCNT, 0, NULL);
  1672.  nacl = acl (filename, GETACL, nacl, aclbufp);
  1673.  
  1674.  if (stat(filename, &sb) != 0)
  1675.     {
  1676.     CfLog(cferror,"","stat");
  1677.     return -1;
  1678.     }
  1679.  
  1680.  Verbose(" Old acl has %d entries and is:\n", nacl);
  1681.  
  1682.  for (i = 0; i < nacl; i++)
  1683.     {
  1684.     Debug1(" a_type = %x, \ta_id = %d, \ta_perm = %o\n",
  1685.        aclbufp[i].a_type, aclbufp[i].a_id, aclbufp[i].a_perm);
  1686.     }
  1687.  
  1688.  Debug1("method = %c\n", method);
  1689.  
  1690.  if (method == 'a')
  1691.     {
  1692.     newacls = nacl;
  1693.     for (i = 0; i < nacl; i++)
  1694.        {
  1695.        newaclbufp[i].a_id = aclbufp[i].a_id;
  1696.        newaclbufp[i].a_type = aclbufp[i].a_type;
  1697.        newaclbufp[i].a_perm = aclbufp[i].a_perm;
  1698.        }
  1699.     }   
  1700.  
  1701.  for (ep = aces; ep !=NULL; ep = ep->next)
  1702.     {
  1703.     if (ep->name == NULL)
  1704.        {
  1705.        continue;
  1706.        }
  1707.     if(IsExcluded(ep->classes))
  1708.        {
  1709.        continue;
  1710.        }
  1711.     
  1712.     Verbose("%s: Mode =%s, name=%s, type=%s\n",VPREFIX,ep->mode,ep->name,ep->acltype);
  1713.     if (strcmp(ep->name, "*") == 0)
  1714.        {
  1715.        bzero (ep->name, sizeof(ep->name));
  1716.        }
  1717.     
  1718.     if (BuildAclEntry(&sb,ep->acltype,ep->name,&tmpacl) == 0)
  1719.        {
  1720.        status = 0;
  1721.        for (i = 0; i < newacls; i++)
  1722.       {
  1723.       if (newaclbufp[i].a_id == tmpacl.a_id && newaclbufp[i].a_type == tmpacl.a_type)
  1724.          {
  1725.          status = 1;
  1726.          if (strcmp(ep->mode, "default") == 0)
  1727.         {
  1728.         sprintf(OUTPUT,"Deleting ACL entry %d: type = %x,\tid = %d,\tperm = %o\n",
  1729.             i, newaclbufp[i].a_type, newaclbufp[i].a_id, newaclbufp[i].a_perm);
  1730.         CfLog(cfverbose,OUTPUT,"");
  1731.         newacls--;
  1732.         newaclbufp[i].a_id = newaclbufp[newacls].a_id;
  1733.         newaclbufp[i].a_type = newaclbufp[newacls].a_type;
  1734.         newaclbufp[i].a_perm = newaclbufp[newacls].a_perm;
  1735.         }
  1736.          else
  1737.         {
  1738.         tmpacl.a_perm = ParseSolarisMode(ep->mode, newaclbufp[i].a_perm);
  1739.         if (tmpacl.a_perm != newaclbufp[i].a_perm)
  1740.            {
  1741.            newaclbufp[i].a_id = tmpacl.a_id;
  1742.            newaclbufp[i].a_type = tmpacl.a_type;
  1743.            newaclbufp[i].a_perm = tmpacl.a_perm;
  1744.            
  1745.            sprintf(OUTPUT,"Replaced ACL entry %d: type = %x,\tid = %d,\tperm = %o\n",
  1746.                i, newaclbufp[i].a_type, newaclbufp[i].a_id, newaclbufp[i].a_perm);
  1747.            CfLog(cfverbose,OUTPUT,"");
  1748.            }
  1749.         }
  1750.          }
  1751.       }
  1752.        }
  1753.     if (status == 0 && (strcmp(ep->mode, "default") != 0))
  1754.        {
  1755.        newaclbufp[newacls].a_id = tmpacl.a_id;
  1756.        newaclbufp[newacls].a_type = tmpacl.a_type;
  1757.        newaclbufp[newacls].a_perm = ParseSolarisMode(ep->mode, 0);
  1758.        newacls++;
  1759.        
  1760.        sprintf(OUTPUT,"Added ACL entry %d: type = %x,\tid = %d,\tperm = %o\n",
  1761.            i, newaclbufp[i].a_type, newaclbufp[i].a_id, newaclbufp[i].a_perm);
  1762.        CfLog(cfverbose,OUTPUT,"");
  1763.        }
  1764.     }
  1765.  
  1766.  if (newacls != nacl)
  1767.     {
  1768.     update = 1;
  1769.     }
  1770.  else
  1771.     {
  1772.     for (i = 0 ; i < nacl ; i++)
  1773.        {
  1774.        status = 0;
  1775.        for (j = 0 ; j < newacls ; j++)
  1776.       {
  1777.       if (aclbufp[i].a_id == newaclbufp[j].a_id && aclbufp[i].a_type == newaclbufp[j].a_type && aclbufp[i].a_perm == newaclbufp[j].a_perm)
  1778.          {
  1779.          status = 1;
  1780.          }
  1781.       }
  1782.        if (status == 0)
  1783.        update = 1;
  1784.        }
  1785.     }
  1786.  
  1787.  if (update == 0)
  1788.     {
  1789.     Verbose("no update necessary\n");
  1790.     return false;
  1791.     }
  1792.  
  1793.  if (action == warnall || action == warnplain || action == warndirs)
  1794.     {
  1795.     sprintf(OUTPUT,"File %s needs ACL update\n",filename);
  1796.     CfLog(cfinform,OUTPUT,"");
  1797.     return false;
  1798.     }
  1799.  
  1800.  if ((status = aclcheck(newaclbufp, newacls, &i)) != 0)
  1801.     {
  1802.     printf("aclcheck failed\n");
  1803.     aclsortperror(status);
  1804.     return false;
  1805.     }
  1806.  
  1807.  if (aclsort(newacls, 0, (aclent_t *) newaclbufp) != 0)
  1808.     {
  1809.     printf("%s: aclsort failed\n", VPREFIX);
  1810.     return false;
  1811.     }
  1812.  
  1813.  Debug1("new acl has %d entries and is:\n", newacls);
  1814.  for (i = 0; i < newacls; i++)
  1815.     {
  1816.     Debug1 ("a_type = %x,\ta_id = %d,\ta_perm = %o\n",
  1817.         newaclbufp[i].a_type, newaclbufp[i].a_id, newaclbufp[i].a_perm);
  1818.     }
  1819.  
  1820.  Debug1("setting acl of %s with %d acl-entries\n", filename, newacls);
  1821.  
  1822.  myuid = getuid();
  1823.  if (sb.st_uid != myuid)
  1824.     {
  1825.     if (myuid == 0)
  1826.        {
  1827.        Verbose("Changing effective uid to %ld\n", (long)sb.st_uid);
  1828.        if (seteuid(sb.st_uid) == -1)
  1829.           {
  1830.       sprintf(OUTPUT,"Couldn't set effective uid from %ld to %ld\n",(long)myuid,(long)sb.st_uid);
  1831.       CfLog(cferror,OUTPUT,"seteuid");
  1832.       return false;
  1833.           }
  1834.        Debug1("effective uid now %ld\n", (long)sb.st_uid);
  1835.        }
  1836.     else
  1837.        {
  1838.        sprintf(OUTPUT,"Can't set effective uid from %ld to %ld, not super-user!\n",
  1839.            (long)myuid, (long)sb.st_uid);
  1840.        CfLog(cferror,OUTPUT,"seteuid");
  1841.        return false;
  1842.        }
  1843.     
  1844.     Debug1("now the correct uid to manage acl of %s\n", filename, newacls);
  1845.     
  1846.     
  1847.     if (acl (filename, SETACL, newacls, newaclbufp) != newacls)
  1848.        {
  1849.        CfLog(cferror,"","acl");
  1850.        return false;
  1851.        }
  1852.     
  1853.     Debug1("setting acl of %s resulted in %d acl-entries\n",
  1854.            filename, newacls);
  1855.     
  1856.     if (seteuid(myuid) == -1)
  1857.        {
  1858.        sprintf(OUTPUT,"Unable to regain privileges of user %ld\n",
  1859.            (long)myuid);
  1860.        CfLog(cferror,OUTPUT,"seteuid");
  1861.        FatalError("Aborting cfengine");
  1862.        }
  1863.     }
  1864.  else
  1865.     {
  1866.     if (acl(filename, SETACL, newacls, newaclbufp) != newacls)
  1867.        {
  1868.        CfLog(cferror,"","acl");
  1869.        return false;
  1870.        }
  1871.     Debug1("setting acl of %s resulted in %d acl-entries\n", filename, newacls);
  1872.     }
  1873.  
  1874.  sprintf(OUTPUT,"ACL for file %s updated\n",filename);
  1875.  CfLog(cfinform,OUTPUT,"");
  1876.  
  1877.  return true;
  1878. #else
  1879.  Verbose("Can't do ACLs on this system...\n");
  1880. #endif
  1881. }
  1882.  
  1883. /*****************************************************************************/
  1884.  
  1885.  
  1886. CheckDFSACE(aces,method,filename,action)
  1887. struct CFACE *aces;
  1888. char method;
  1889. char *filename;
  1890. enum fileactions action;
  1891. {
  1892. #ifdef HAVE_DCE
  1893.  
  1894.  struct CFACE *ep;
  1895.  sec_acl_handle_t h;
  1896.  sec_acl_list_t acl_list;
  1897.  error_status_t status;
  1898.  unsigned32 size_used, num_types;
  1899.  uuid_t manager_types[SIZE_AVAIL];
  1900.  sec_rgy_handle_t rgy_site;
  1901.  uuid_t cell_uuid;
  1902.  sec_rgy_properties_t properties;
  1903.  sec_acl_p_t new_sec_acls[1];
  1904.  int update = 0;
  1905.  int index = 0;
  1906.  int i, j;
  1907.  sec_acl_entry_type_t type;
  1908.  sec_acl_permset_t perms, ptmp;
  1909.  uuid_t id;
  1910.  
  1911.  sec_rgy_site_open ("/.:", &rgy_site, &status);
  1912.  
  1913.  if (status != error_status_ok)
  1914.     {
  1915.     sprintf(OUTPUT,"DCE: sec_rgy_site_open: %ld\n", status);
  1916.     CfLog(cferror,OUTPUT,"");
  1917.     }
  1918.  
  1919.  sec_id_parse_name (rgy_site, "", NULL, &cell_uuid, NULL, NULL, &status);
  1920.  
  1921.  if (status != error_status_ok)
  1922.     {
  1923.     sprintf(OUTPUT,"DCE: sec_rgy_parse_name: %ld\n", status);
  1924.     CfLog(cferror,OUTPUT,"");
  1925.     }
  1926.  
  1927.  sec_rgy_properties_get_info(rgy_site, &properties, &status);
  1928.  if (status != error_status_ok)
  1929.     {
  1930.     sprintf(OUTPUT,"DCE: sec_rgy_properties_get_info: %ld\n", status);
  1931.     CfLog(cferror,OUTPUT,"");
  1932.     }
  1933.  
  1934.  sec_acl_bind (filename, FALSE, &h, &status);
  1935.  
  1936.  if (status != error_status_ok)
  1937.     {
  1938.     sprintf(OUTPUT,"DCE: sec_acl_bind: %ld\n", status);
  1939.     CfLog(cferror,OUTPUT,"");
  1940.     }
  1941.  
  1942.  sec_acl_get_manager_types (h, sec_acl_type_object, SIZE_AVAIL,
  1943.                             &size_used, &num_types, manager_types, &status);
  1944.  
  1945.  if (status != error_status_ok)
  1946.     {
  1947.     sprintf(OUTPUT,"DCE: sec_acl_get_manager_types: %ld\n", status);
  1948.     CfLog(cferror,OUTPUT,"");
  1949.     }
  1950.  
  1951.  if (num_types == 0)
  1952.     {
  1953.     sprintf(OUTPUT,"DCE: No ACL manager!\n");
  1954.     CfLog(cferror,OUTPUT,"");
  1955.     }
  1956.  
  1957.  if (size_used < num_types)
  1958.     {
  1959.     sprintf(OUTPUT,"Warning: some manager types missed\n");
  1960.     CfLog(cfsilent,OUTPUT,"");
  1961.     }
  1962.  
  1963.  sec_acl_lookup (h, manager_types, sec_acl_type_object, &acl_list, &status);
  1964.  
  1965.  if (status != error_status_ok)
  1966.     {
  1967.     sprintf (OUTPUT,"DCE: sec_acl_lookup: %ld\n", status);
  1968.     CfLog(cferror,OUTPUT,"");
  1969.     }
  1970.  
  1971.  Debug1("method = %c\n", method);
  1972.  
  1973.  /* new_sec_acls[0]= calloc(1, sizeof(sec_acl_p_t));*/
  1974.  new_sec_acls[0]= calloc(1, sizeof(sec_acl_t));
  1975.  
  1976.  new_sec_acls[0]->sec_acl_entries = calloc(MAXDFSACL, sizeof(sec_acl_entry_t));
  1977.  new_sec_acls[0]->default_realm = acl_list.sec_acls[0]->default_realm;
  1978.  new_sec_acls[0]->sec_acl_manager_type = acl_list.sec_acls[0]->sec_acl_manager_type;
  1979.  new_sec_acls[0]->num_entries = 0;
  1980.  
  1981.  if (method == 'a')
  1982.     {
  1983.     new_sec_acls[0]->num_entries = acl_list.sec_acls[0]->num_entries;
  1984.     for (i = 0; i < acl_list.sec_acls[0]->num_entries; i++)
  1985.        {
  1986.        new_sec_acls[0]->sec_acl_entries[i].entry_info.entry_type = acl_list.sec_acls[0]->sec_acl_entries[i].entry_info.entry_type;
  1987.        new_sec_acls[0]->sec_acl_entries[i].perms = acl_list.sec_acls[0]->sec_acl_entries[i].perms;
  1988.        new_sec_acls[0]->sec_acl_entries[i].entry_info.tagged_union = acl_list.sec_acls[0]->sec_acl_entries[i].entry_info.tagged_union;
  1989.        }
  1990.     }
  1991.  
  1992.  for (ep = aces; ep !=NULL; ep = ep->next)
  1993.     {
  1994.     if (ep->name == NULL)
  1995.        {
  1996.        continue;
  1997.        }
  1998.     
  1999.     if(IsExcluded(ep->classes))
  2000.        {
  2001.        continue;
  2002.        }
  2003.     
  2004.     Verbose("%s: Mode =%s, name=%s, type=%s\n",VPREFIX,ep->mode,ep->name,ep->acltype);
  2005.     if (strcmp(ep->name, "*") == 0)
  2006.        {
  2007.        bzero (ep->name, sizeof(ep->name));
  2008.        }
  2009.     
  2010.     type = BuildDceAclEntry_Type(ep->acltype,ep->name);
  2011.     
  2012.     if (strlen(ep->name) != 0)
  2013.        {
  2014.        id = BuildDceAclEntry_Id(rgy_site, ep->name, type);
  2015.        }
  2016.     
  2017.     status = 0;
  2018.     for (i = 0; i < new_sec_acls[0]->num_entries; i++)
  2019.        {
  2020.        if (new_sec_acls[0]->sec_acl_entries[i].entry_info.entry_type == type &&
  2021.        ((strlen(ep->name) != 0 && bcmp(new_sec_acls[0]->sec_acl_entries[i].entry_info.tagged_union.id.uuid, id, sizeof(uuid_t)) == 0) || strlen(ep->name) == 0))
  2022.       {
  2023.       status = 1;
  2024.       if (strcmp(ep->mode, "default") == 0)
  2025.          {
  2026.          new_sec_acls[0]->num_entries--;
  2027.          new_sec_acls[0]->sec_acl_entries[i] = new_sec_acls[0]->sec_acl_entries[new_sec_acls[0]->num_entries];
  2028.          }
  2029.       else
  2030.          {
  2031.          new_sec_acls[0]->sec_acl_entries[i].perms = BuildDceAclEntry_Perms(ep->mode, new_sec_acls[0]->sec_acl_entries[i].perms);
  2032.          }
  2033.       }
  2034.        }
  2035.     if (status == 0 && strcmp(ep->mode, "default") != 0)
  2036.        {
  2037.        if (strlen(ep->name) != 0)
  2038.       {
  2039.       new_sec_acls[0]->sec_acl_entries[new_sec_acls[0]->num_entries].entry_info.tagged_union.id.uuid = id;
  2040.       }
  2041.        new_sec_acls[0]->sec_acl_entries[new_sec_acls[0]->num_entries].entry_info.entry_type = type;
  2042.        new_sec_acls[0]->sec_acl_entries[new_sec_acls[0]->num_entries++].perms = BuildDceAclEntry_Perms(ep->mode, 0);
  2043.        }
  2044.     }
  2045.  
  2046.  status = 0;
  2047.  sec_rgy_site_close (rgy_site, &status);
  2048.  if (status != error_status_ok)
  2049.     {
  2050.     printf ("error: sec_rgy_site_close: %ld\n", status);
  2051.     }
  2052.  
  2053.  if (acl_list.sec_acls[0]->num_entries != new_sec_acls[0]->num_entries)
  2054.     {
  2055.     update = 1;
  2056.     }
  2057.  else
  2058.     {
  2059.     for (i = 0; i < acl_list.sec_acls[0]->num_entries; i++)
  2060.        {
  2061.        status = 0;
  2062.        for (j = 0; j < new_sec_acls[0]->num_entries; j++)
  2063.       {
  2064.       if (new_sec_acls[0]->sec_acl_entries[j].perms == acl_list.sec_acls[0]->sec_acl_entries[i].perms &&
  2065.           new_sec_acls[0]->sec_acl_entries[j].entry_info.entry_type == acl_list.sec_acls[0]->sec_acl_entries[i].entry_info.entry_type &&
  2066.           bcmp(new_sec_acls[0]->sec_acl_entries[j].entry_info.tagged_union.id.uuid,acl_list.sec_acls[0]->sec_acl_entries[i].entry_info.tagged_union.id.uuid, sizeof(uuid_t)) == 0)
  2067.          {
  2068.          status = 1;
  2069.          }
  2070.       }
  2071.        if (status == 0)
  2072.       {
  2073.       update = 1;
  2074.       }
  2075.        }
  2076.     }
  2077.  
  2078.  status = 0;
  2079.  
  2080.  if (update == 0)
  2081.     {
  2082.     Verbose("%s: No update necessary\n",VPREFIX);
  2083.     return false;
  2084.     }
  2085.  else
  2086.     {
  2087.     if (action == warnall || action == warnplain || action == warndirs)
  2088.        {
  2089.        sprintf(OUTPUT,"File %s needs ACL update\n",filename);
  2090.        CfLog(cfinform,OUTPUT,"");
  2091.        return false;
  2092.        }
  2093.     acl_list.sec_acls[0] = new_sec_acls[0];
  2094.     sec_acl_replace (h, manager_types, sec_acl_type_object, &acl_list, &status);
  2095.     if (status != error_status_ok)
  2096.        {
  2097.        printf ("error: sec_acl_replace: %ld\n", status);
  2098.        return false;
  2099.        }
  2100.     else
  2101.        {
  2102.        sprintf(OUTPUT,"ACL for file %s updated\n",filename);
  2103.        CfLog(cfinform,OUTPUT,"");
  2104.        return true;
  2105.        }
  2106.     }
  2107.  return true;
  2108. #endif
  2109. }
  2110.